package com.homedo.microservice.open.service.gateway.zuul.processor;

import com.google.common.collect.Lists;
import com.homedo.common.util.Detect;
import com.homedo.microservice.open.service.gateway.zuul.conf.ZuulFilterActiveConf;
import com.netflix.zuul.FilterLoader;
import com.netflix.zuul.FilterProcessor;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.Debug;
import com.netflix.zuul.context.RequestContext;

import java.util.List;

/**
 * 过滤器执行器
 */
public class LocalFilterProcessor extends FilterProcessor {
    static LocalFilterProcessor INSTANCE = new LocalFilterProcessor();

    private LocalFilterProcessor() {
        super();
    }

    public static FilterProcessor getInstance() {
        return INSTANCE;
    }

    @Override
    public Object runFilters(String sType) throws Throwable {
        if (RequestContext.getCurrentContext().debugRouting()) {
            Debug.addRoutingDebug("Invoking {" + sType + "} type filters");
        }
        boolean bResult = false;
        List<ZuulFilter> list = FilterLoader.getInstance().getFiltersByType(sType);

        list = this.getActiveZuulFilters(list);

        if (Detect.notEmpty(list)) {
            for (int i = 0; i < list.size(); i++) {
                ZuulFilter zuulFilter = list.get(i);
                Object result = processZuulFilter(zuulFilter);
                if (result != null && result instanceof Boolean) {
                    bResult |= ((Boolean) result);
                }
            }
        }
        return bResult;
    }

    /**
     * 排除非启用的过滤器
     *
     * @param zuulFilters
     * @return
     */
    private List<ZuulFilter> getActiveZuulFilters(List<ZuulFilter> zuulFilters) {
        if (!Detect.notEmpty(zuulFilters)) {
            return null;
        }
        List<String> activeFilterNames = ZuulFilterActiveConf.getInstance().getActiveFilterNames();
        if (!Detect.notEmpty(activeFilterNames)) {
            return null;
        }

        List<ZuulFilter> activeZuulFilter = Lists.newArrayList();

        zuulFilters.forEach(e -> {
            if (activeFilterNames.contains(e.getClass().getSimpleName())) {
                activeZuulFilter.add(e);
            }
        });

        return activeZuulFilter;
    }
}
